/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ga_checkpoint5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *  This class defines the entities that will be composing the population upon
 * which our genetic algorithm will be running on.
 * @author Asif Dipon, Harshal Joshi
 */
public class TourPath implements Comparable{

    //the unique id of the TourPath
    protected int id;
    //an ordered list containing the cities that will be visited in the order they
    //appear.
    protected List<City> tour;
    //Number of times selected.
    protected int numTimesSelected;

    /**
     * Basic Constructor
     * @param id    The unique id
     */
    public TourPath(int id){
        this(id, new ArrayList<City>());
    }

    /**
     * Constructor that takes an id and tour path
     * @param id    The unique id
     * @param path  The tour path
     */
    public TourPath(int id, List<City> path){
        this.id = id;
        this.tour = new ArrayList<City>();
        for(City c: path){
            this.tour.add(c);
        }
        this.numTimesSelected = 1;
    }

    /**
     * Gets the fitness of the tour path which is the total distance covered.
     */
    public double getFitness(){
        double totalDistance = 0;
        for(int i=0; i<this.tour.size()-1; i++){
            City a = this.tour.get(i);
            City b = this.tour.get(i+1);
            double subTotal = Math.sqrt(Math.pow(a.xcor - b.xcor, 2) + Math.pow(a.ycor - b.ycor, 2));
            totalDistance += subTotal;
        }
        return totalDistance;
    }

    /**
     * Implementation of the compareTo function.
     * @param o
     * @return
     */
    public int compareTo(Object o) {
        TourPath other = (TourPath)o;
        double diff = this.getFitness() - other.getFitness();
        if (diff >0) return 1;
        else if (diff < 0) return -1;
        else return 0;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final TourPath other = (TourPath) obj;
        if (this.id != other.id) {
            return false;
        }
        if (this.tour != other.tour && (this.tour == null || !this.tour.equals(other.tour))) {
            return false;
        }
        if (this.getFitness() != other.getFitness()) {
            return false;
        }
        return true;
    }

    

    @Override
    public String toString() {
        String s = "";
        for(City c: this.tour){
            s+= c;
        }
        return s;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 79 * hash + this.id;
        return hash;
    }

}
